% The code is based on the following paper:
%   Chen, T. Y., Lin, Y. L., and Tzeng, L. Y., forthcoming.
%   Estimating probability weighting functions through option pricing bounds. Review of Asset Pricing Studies.
%
% Copyright: Tzu-Ying Chen, Yo-Lan Lin, Larry Y. Tzeng
% Date: January 30, 2024

clear
      
%% Setting
BV_Target = {'UB'};                                                        

%% Load Data
FileName = ['AllTradingDate19962021_Monthly.mat'];
load(FileName, ...
     'Target_AllDate');             
clear FileName

Date_Monthly = Target_AllDate;
clear Target_AllDate 

%% Option Pricing Bounds for Each Parameters
AllData = [];                                                              
for d = 1:size(Date_Monthly, 1)
    Target_Date = Date_Monthly(d, 1);
    Target_TTM = Date_Monthly(d, 3);

    FileName = ['OP' num2str(Target_Date) '_TTM' num2str(Target_TTM) '.mat'];
    load(FileName, ...
         'Data', ...
         'Index_Date', 'Index_TTM', 'Index_CPFlag', 'Index_K', 'Index_OP_Bid', 'Index_OP_Ask', ...
         'Index_RF', 'Index_DY', 'Index_IS', 'Index_IS_ADJ', 'Index_IV_Bid', 'Index_IV_Ask');
    clear FileName 

    Index_Drop = find(sum(isnan(Data(:, [Index_IV_Bid Index_IV_Ask])), 2) > 0);
    Data(Index_Drop, :) = [];                                              
    AllData = [AllData; Data];
    clear Index_Drop Data
    clear Target_Date Target_TTM     
end
clear d

K = AllData(:, Index_K);
S0 = AllData(:, Index_IS);
Index_KS = size(AllData, 2) + 1;
AllData(:, Index_KS) = K ./ S0;                                            
AllData = sortrows(AllData, Index_KS);                                     
clear K S0

OP_Bid = AllData(:, Index_OP_Bid);
OP_Ask = AllData(:, Index_OP_Ask);

for d = 1:size(Date_Monthly, 1)
    Target_Date = Date_Monthly(d, 1);
    Target_TTM = Date_Monthly(d, 3);
    
    FileName = ['Summary_AIO_OP_Grid_' num2str(Target_Date)];
    load(FileName, ...
         'Record', 'Record_OP_LB', 'Record_OP_UB', ...
         'K');       
    clear FileName        

    if d==1
        OP_UB = nan(size(AllData, 1), size(Record, 1));                    
    else
    end
    [Index_Exist Index_Location] = ismember(AllData(:, [Index_Date Index_K]), ...
                                            [(Target_Date * ones(size(K))) K], ...
                                            'rows');
    Index_Location(Index_Location==0) = [];                                                                    
    OP_UB(Index_Exist, :) = Record_OP_UB(:, Index_Location)';
    clear Index_Exist Index_Location
        
    if d < size(Date_Monthly, 1)
        clear Record
    else
    end
    clear Target_Date Target_TTM
    clear Record_OP_LB Record_OP_UB
    clear K
end
OP_UB = max(OP_UB, 0);                                                      
DEV_UB = sum(OP_UB ./ OP_Bid, 1);  
clear d

%% Optimal Risk Preference under Rank-Dependent Expected Utility
Index = find(sum(OP_UB >= OP_Bid, 1)==length(OP_Bid));   

[AllDEV, ~, Index_AllDEV] = unique(DEV_UB(Index));    
Index = Index(Index_AllDEV==1)';                                               
OPT_TAB = [ones(size(Index)) Record(Index, 1:2) nan(size(Index)) nan(size(Index)) DEV_UB(Index)];
clear Index AllDEV Index_AllDEV
clear Record 

Index_OPT = 1 + [1 2];                                                     
Index_CR = 1;

%% Output
FileName = ['Summary_AIO_OPT_AllPeriod_OP_UB'];
save(FileName, ...
     'Index_CR', 'Index_OPT', 'OPT_TAB', ...
     'AllData', ...
     'Index_Date', 'Index_TTM', 'Index_CPFlag', 'Index_K', 'Index_OP_Bid', 'Index_OP_Ask', ...
     'Index_RF', 'Index_DY', 'Index_IS', 'Index_IS_ADJ', 'Index_IV_Bid', 'Index_IV_Ask');
clear FileName 

clear Index_ID Index_Date Index_TTM Index_CPFlag Index_K Index_S Index_F Index_OP_Bid Index_OP_Ask Index_OI Index_V
clear Index_RF Index_DY Index_IS Index_IS_ADJ Index_S_ADJ Index_IV_Bid Index_IV_Ask Index_KS